<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>104Slaver</title>
</head>
<style>
    td {
        width: 90px;
        text-align: center;
        border: 1px black solid;
    }

    td:nth-child(2), td:nth-child(4), td:nth-child(6), td:nth-child(8) {
        background: #ff0000;
    }

    td:nth-child(1), td:nth-child(3), td:nth-child(5), td:nth-child(7) {
        background: #23B72BFF;
    }

    .th td {
        background: white !important;
    }
</style>
<body>
<div>
    <table style="margin-left: 10px">
        <tbody id="wt">
        <tr class="th">
            <td style="border: none"><input type="button" value="导出配置" onclick="exportConfig()"></td>
            <td style="border: none" colspan="4"><input type="file" value="选择配置文件" id="configFileInput"></td>
            <td style="border: none"><input type="button" value="导入配置" onclick="uploadConfig()"></td>
        </tr>
        <tr style="height: 10px">
            <td colspan="8" style="text-align: left;color: red;background-color: white">
                16385（4001H）之后的点位默认遥测，之前的点位默认遥信
            </td>
        </tr>
        <tr style="height: 10px">
            <td colspan="8" style="text-align: left;color: red;background-color: white">
                <ul style="margin: 0">
                    输入公式时,须保证公式的准确性，遥信保证结果为布尔值，遥测保证结果为数值
                    <li>"T()" 代表当前时间戳</li>
                    <li>"R()" 代表0-1的浮点值</li>
                    <li>"R(n)" 代表0-n的长整值</li>
                    <li>"P(n)" 代表当下n点位的值</li>
                </ul>
            </td>
        </tr>
        <tr>
            <td>点位</td>
            <td>值</td>
            <td>点位</td>
            <td>值</td>
            <td>点位</td>
            <td>值</td>
            <td>点位</td>
            <td>值</td>
        </tr>
        </tbody>
    </table>
    <input style="margin: 10px 10px" type="button" value="+" id="addBut">
    <input style="margin: 10px 10px" type="button" value="保存" id="save">

</div>
</body>
</html>
<script>
    function ajax() {
        var ajaxData = {
            type: arguments[0].type || "GET",
            url: arguments[0].url || "",
            async: arguments[0].async || "true",
            data: arguments[0].data || null,
            dataType: arguments[0].dataType || "text",
            contentType: arguments[0].contentType || "application/x-www-form-urlencoded",
            beforeSend: arguments[0].beforeSend || function () {
            },
            success: arguments[0].success || function () {
            },
            error: arguments[0].error || function () {
            }
        }
        ajaxData.beforeSend()
        var xhr = createxmlHttpRequest();
        xhr.responseType = ajaxData.dataType;
        xhr.open(ajaxData.type, ajaxData.url, ajaxData.async);
        xhr.setRequestHeader("Content-Type", ajaxData.contentType);
        xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
        xhr.send(convertData(ajaxData.data));
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                if (xhr.status == 200) {
                    ajaxData.success(xhr.response)
                } else {
                    ajaxData.error()
                }
            }
        }
    }

    function createxmlHttpRequest() {
        if (window.ActiveXObject) {
            return new ActiveXObject("Microsoft.XMLHTTP");
        } else if (window.XMLHttpRequest) {
            return new XMLHttpRequest();
        }
    }

    function convertData(data) {
        if (typeof data === 'object') {
            var convertResult = "";
            for (var c in data) {
                convertResult += c + "=" + data[c] + "&";
            }
            convertResult = convertResult.substring(0, convertResult.length - 1)
            return convertResult;
        } else {
            return data;
        }
    }

    var wTable = document.getElementById("wt")
    var isInput = false;

    function addPoint() {
        if (isInput) {
            return
        }
        var lastTr = wTable.lastElementChild
        if (lastTr.childElementCount > 6) {
            wTable.appendChild(document.createElement("tr"))
        }
        wTable.lastElementChild.appendChild(getTd(getInputPointEle()))
        wTable.lastElementChild.appendChild(getTd(getInputValueEle()))
        isInput = true
    }


    function getTd(child) {
        var td = document.createElement("td")
        td.appendChild(child)
        return td

    }

    function getInputPointEle() {
        var inputE = document.createElement("input")
        inputE.type = "text"
        inputE.placeholder = "输入点位"
        inputE.style.cssText = 'width: 82px';
        inputE.classList.add("open-point")
        inputE.onchange = checkValue;
        return inputE
    }

    function getInputValueEle() {
        var inputE = document.createElement("input")
        inputE.type = "text"
        inputE.placeholder = "输入值或公式"
        inputE.style.cssText = 'width: 82px';
        inputE.classList.add("open-value")
        inputE.onchange = checkValue;
        return inputE
    }

    function checkValue() {
        var valueE = document.getElementsByClassName("open-value")[0];
        var value = valueE.value
        if (value == "true" || value == "false" || /^(-?\d+)(\.\d+)?$/.test(value)) {
            // 固定值
            return 1;
        } else {
            //公式
            return 2;
        }
    }

    function checkPoint() {
        var pointE = document.getElementsByClassName("open-point")[0];
        var point = pointE.value
        if (!(/^[1-9]\d*$/.test(point))) {
            console.log('输入的不是正整数');
            pointE.focus();
            return null;
        } else {
            return point
        }
    }

    function getValues() {
        ajax({
            type: "GET",
            url: "/getValues",
            success: function (msg) {
                var ps = JSON.parse(msg)
                for (var p in ps) {
                    if (document.getElementById("td_" + p) != null) {
                        document.getElementById("td_" + p).innerText = ps[p]
                    }
                }
            },
            error: function () {
            }
        })
    }

    function buildPage() {
        ajax({
            type: "GET",
            url: "/getAllPoints",
            success: function (msg) {
                var points = JSON.parse(msg)
                var tr;
                var td;
                var i = 0;
                for (var p in points) {
                    if (i % 4 == 0) {
                        tr = wTable.appendChild(document.createElement("tr"))
                    }
                    td = document.createElement("td");
                    td.id = td.id = "tdp_" + p
                    td.innerHTML = p;
                    td.ondblclick = dbChickOnPoint
                    tr.appendChild(td);
                    td = document.createElement("td");
                    td.id = "td_" + p
                    td.title = points[p]
                    td.ondblclick = dbChickOnValue
                    tr.appendChild(td);
                    i++;
                }
            },
            error: function () {
                alert("error")
            }
        })
    }

    buildPage();

    setInterval(getValues, 10);

    function savePoint() {
        var pointE = document.getElementsByClassName("open-point")[0];
        var valueE = document.getElementsByClassName("open-value")[0];
        if (pointE == null) {
            return;
        }
        if (checkPoint() != null) {
            if (checkValue() == 1) {
                ajax({
                    type: "GET",
                    url: "/addConstantPoint?point=" + checkPoint() + "&value=" + escape(valueE.value).replace(/\+/g, '%2B'),
                    success: function (msg) {
                        location.reload();
                    },
                    error: function () {
                        console.log("error")
                    }
                })
            } else {
                ajax({
                    type: "GET",
                    url: "/addCalculatorPoint?point=" + checkPoint() + "&value=" + escape(valueE.value).replace(/\+/g, '%2B'),
                    success: function (msg) {
                        location.reload();
                    },
                    error: function () {
                        console.log("error")
                    }
                })
            }
        } else {
            if (pointE.id == null || pointE.id == "") {
                var grand = pointE.parentNode.parentNode
                grand.removeChild(pointE.parentNode)
                grand.removeChild(valueE.parentNode)
                isInput = false;
                return;
            } else {
                ajax({
                    type: "GET",
                    url: "/deletePoint?point=" + pointE.id.substr(6, pointE.id.length - 6),
                    success: function (msg) {
                        location.reload();
                    },
                    error: function () {
                        console.log("error")
                    }
                })
            }
        }
    }

    function dbChickOnPoint() {
        modifyPoint(this.id.substr(4, this.id.length - 4))
    }

    function dbChickOnValue() {
        modifyPoint(this.id.substr(3, this.id.length - 3))
    }

    function modifyPoint(point) {
        if (!isInput) {
            var fe = document.getElementById("tdp_" + point);
            var ch = getInputPointEle();
            fe.innerText = ""
            fe.appendChild(ch);
            ch.value = point
            ch.id = "input_" + point;
            fe = document.getElementById("td_" + point);
            ch = getInputValueEle();
            ch.value = fe.title;
            fe.innerText = ""
            fe.id = ""
            fe.appendChild(ch);
            isInput = true;
        }
    }

    document.getElementById("addBut").addEventListener("click", addPoint);
    document.getElementById("save").addEventListener("click", savePoint);

    function downloadFile(fileName, context) {
        var link = document.createElement('a');
        link.download = fileName;
        link.style.display = 'none';
        link.href = URL.createObjectURL(new Blob([context]));
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    }

    function exportConfig() {
        ajax({
            type: "GET",
            url: "/getAllPoints",
            success: function (msg) {
                downloadFile("104slaver.conf", msg)
            },
            error: function () {
                alert("获取配置失败")
            }
        })


    }

    function uploadConfig() {
        var f = document.getElementById("configFileInput");
        var file = f.files[0]
        if (file != null && file.size < 1024 * 1024) {
            var fileReader = new FileReader()
            fileReader.readAsText(file)
            fileReader.onload = function () {
                try {
                    var str = fileReader.result
                    var re = JSON.parse(str);
                    ajax({
                        type: "POST",
                        url: "/uploadConfig",
                        data: str,
                        dataType: 'json',
                        contentType: 'application/json',
                        success: function (msg) {
                            location.reload();
                        },
                        error: function () {
                            alert("获取配置失败")
                        }
                    })
                } catch (e) {
                    alert(e)
                }
            }
        }
    }

</script>